package djrain.lilochat.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

class Client extends Thread
{

	private static final String HELPMESSAGE = "/note\n" 
		+ "==================================\n" 
		+ "  /?, /help : 도움말을 봅니다.\n" 
		+ "  /al  : 대화명을 변경합니다.\n" 
		+ "  /all : 모든 사람에게 말을 겁니다.\n"
		+ "  /bye, /exit, /quit : 나갑니다.\n" 
		+ "===================================\n";

	private Socket socket = null;
	private Server server = null;
	private BufferedReader br = null;
	private BufferedWriter bw = null;

	private String longitude = "-122.08409";
	private String latitude = "37.422006";
	private String username = "";
	private String index;
	private static int INDEXS = 0;

	public String getUsername()
	{
		return username;
	}

	public String getIndex()
	{
		return index;
	}

	public String getLocation()
	{
		return longitude + ":" + latitude;
	}

	public int getPort()
	{
		return socket.getPort();
	}

	public Client(Socket socket, Server server)
	{
		this.socket = socket;
		this.server = server;
		this.index = Integer.toString(++INDEXS);
		try
		{
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		}
		catch (IOException e)
		{
			// Thread kill
		}
		server.Log("New client accept[" + socket.getPort() + "]");
		
		server.addClient(this);
	}

	public void run()
	{
		String str = "";
		while (true)
		{
			try
			{
				str = br.readLine();
				server.Log("<" + "[" + socket.getPort() + "]" + str);
				if (isCommand(str))
				{
					processCommand(str);
				}
				else
				{
					echo(str);
				}
			}
			catch (IOException e)
			{
				closeSocket();
				break;
			}
		}
	}

	private void echo(String str)
	{
		sendMessage(str);

	}

	public boolean isCommand(String str)
	{
		return str.substring(0, 1).equals("/");
	}

	public void processCommand(String command)
	{
		String commandHead = command.substring(0, 5);

		String commandBody = null;
		if(command.length() > 5)
			commandBody = command.substring(5).trim();
		if (commandHead.equalsIgnoreCase("/?   ") || commandHead.equalsIgnoreCase("/help"))
		{ // help
			server.messageTo(this, HELPMESSAGE);
		}
		else if (commandHead.equalsIgnoreCase("/iam "))
		{ // change user name
			username = commandBody;
			server.broadcast("/note" + username + "님께서 입장!");
			server.messageTo(this, HELPMESSAGE);
		}
		else if (commandHead.equalsIgnoreCase("/al  "))
		{ // change user name
			String newname = commandBody;
			server.broadcast("/note" + username + "님께서 \"" + newname + "\"으로 대화명을 바꾸었습니다.");
			username = newname;
		}
		else if (commandHead.equalsIgnoreCase("/all "))
		{ // show all user
			server.broadcastExcept(this, commandBody);
		}
		else if (commandHead.equalsIgnoreCase("/@   "))
		{
			String[] locations = commandBody.split(":");

			if (locations.length != 2)
				return;
			longitude = locations[0];
			latitude = locations[1];
			
			
			server.broadcast(command);
			//server.broadcastExcept(this, server.getLocationAll());
		}
		else
		{
			server.Log("!Unknown Command:" + ">"+command+"<");
		}
	}

	public void sendMessage(String str)
	{
		try
		{
			bw.write(str);
			bw.newLine();
			bw.flush();
		}
		catch (IOException e)
		{
		}
	}

	public void closeSocket()
	{
		try
		{
			br.close();
			bw.close();
			socket.close();
		}
		catch (IOException e)
		{
		}

		server.removeClient(this);
		server.broadcast("/note" + "[" + getUsername() + "]님께서 나가셨습니다.");
	}
}
